package com.cloud.system.project.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cloud.common.core.asserts.ApiAssert;
import com.cloud.common.core.cons.StatusCons;
import com.cloud.common.core.enums.ErrorCodeEnum;
import com.cloud.common.core.model.response.ApiResponses;
import com.cloud.common.core.model.supers.SuperController;
import com.cloud.common.core.utils.poi.ExcelUtil;
import com.cloud.common.security.annotation.PreAuth;
import com.cloud.common.security.utils.ApiUtils;
import com.cloud.system.project.cons.LevelCons;
import com.cloud.system.project.cons.MenuTypeCons;
import com.cloud.system.project.model.dto.MenuTreeDTO;
import com.cloud.system.project.model.dto.UserDTO;
import com.cloud.system.project.model.entity.User;
import com.cloud.system.project.model.parm.UserPARM;
import com.cloud.system.project.service.IMenuService;
import com.cloud.system.project.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统用户表 前端控制器
 * </p>
 *
 * @author Sam
 * @since 2020-12-27
 */
@Api(tags = {"用户信息"})
@RestController
@RequestMapping("/user")
public class UserRestController extends SuperController {

    @Autowired
    private IUserService userService;
    @Autowired
    private IMenuService menuService;

    @PreAuth
    @ApiOperation("查询所有用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "loginName", value = "登录名 模糊", paramType = "query"),
            @ApiImplicitParam(name = "username", value = "真实姓名 模糊", paramType = "query"),
            @ApiImplicitParam(name = "status", value = "用户状态", type = "int", paramType = "query"),
            @ApiImplicitParam(name = "deptId", value = "部门id", type = "int", paramType = "query"),
            @ApiImplicitParam(name = "roleId", value = "角色id", type = "int", paramType = "query"),
    })
    @GetMapping
    public ApiResponses<IPage<UserDTO>> page(@ApiIgnore @ModelAttribute UserPARM userPARM) {
        Page page = this.getPage();
        page.setOptimizeCountSql(false);
        IPage<UserDTO> userIPage = userService.getPage(page, userPARM);
        return success(userIPage);
    }

    @PreAuth
    @ApiOperation(value = "条件查询用户", response = UserDTO.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "loginName", value = "登录名 模糊", paramType = "query"),
            @ApiImplicitParam(name = "username", value = "真实姓名 模糊", paramType = "query"),
            @ApiImplicitParam(name = "status", value = "用户状态", type = "int", paramType = "query"),
            @ApiImplicitParam(name = "roleId", value = "角色id", type = "int", paramType = "query"),
    })
    @GetMapping("/list")
    public ApiResponses<List<UserDTO>> list(@ApiIgnore @ModelAttribute UserPARM userPARM) {
        List<UserDTO> dtoList = userService.getList(userPARM);
        return success(dtoList);
    }

    @PreAuth
    @ApiOperation("单条查询用户")
    @GetMapping("/{id}")
    public ApiResponses<UserDTO> getById(@PathVariable("id") String id) {
        UserDTO user = userService.getByIdEx(id);
        return success(user);
    }

    @PreAuth
    @ApiOperation("新增用户")
    @PostMapping
    public ApiResponses<Void> create(@RequestBody @Validated(value = UserPARM.Create.class) UserPARM userPARM) {
        userPARM.setLevel(LevelCons.USER);
        userService.createUser(userPARM);
        return success();
    }

    @PreAuth
    @ApiOperation("修改用户")
    @PutMapping("/{id}")
    public ApiResponses<Void> updateById(@PathVariable("id") String id, @RequestBody UserPARM userPARM) {
        userPARM.setId(id);
        //过滤不可使用通用修改项
        userPARM.setPassword(null);
        userPARM.setLoginName(null);
        userPARM.setLevel(null);
        User user = userPARM.convert(User.class);
        ApiAssert.isTrue(ErrorCodeEnum.BAD_UPDATE_FAILURE, userService.updateById(user));
        return success();
    }

    @PreAuth
    @ApiOperation("更改状态")
    @PutMapping("/changeStatus")
    public ApiResponses<Void> changeStatus(@RequestBody @Validated({UserPARM.ChangeStatus.class}) UserPARM userPARM) {
        User user = new User();
        user.setId(userPARM.getId());
        user.setStatus(userPARM.getStatus());
        ApiAssert.isTrue(ErrorCodeEnum.INTERNAL_SERVER_ERROR, userService.updateById(user));
        return success();
    }

    @PreAuth
    @ApiOperation("删除用户")
    @DeleteMapping("/{id}")
    public ApiResponses<Void> deleteById(@PathVariable("id") String id) {
        userService.delUser(id);
        return success();
    }

    @PreAuth
    @ApiOperation("删除用户（批量）")
    @DeleteMapping("/batch/{idList}")
    public ApiResponses<Void> deleteBatchById(@PathVariable("idList") List<String> idList) {
        ApiAssert.isTrue(ErrorCodeEnum.BAD_DELETE_FAILURE, userService.update(Wrappers.<User>lambdaUpdate()
                .set(User::getStatus, StatusCons.DISABLE).in(User::getId, idList)));
        return success();
    }

    @PreAuth
    @ApiOperation("用户详细信息（登录）")
    @GetMapping(value = "/profile")
    public ApiResponses<UserDTO> profile() {
        String uid = ApiUtils.currentUid();
        UserDTO userDTO = userService.getByIdEx(uid);
        ApiAssert.notNull(ErrorCodeEnum.INTERNAL_SERVER_ERROR.convert("获取个人信息失败"), userDTO);
        List<MenuTreeDTO> userPermMenus = menuService.getTreeUserPermMenus(uid);
        List<String> userPermButton = menuService.getUserPermMenus(uid, Arrays.asList(MenuTypeCons.BUTTON))
                .stream().map(MenuTreeDTO::getPerm).collect(Collectors.toList());
        userDTO.setMenuTreeDTO(userPermMenus);
        userDTO.setButtonList(userPermButton);
        return success(userDTO);
    }

    @PreAuth
    @ApiOperation("修改密码")
    @PostMapping("/updatePwd")
    public ApiResponses<Void> updatePwd(@RequestBody @Validated(value = UserPARM.UpdatePwd.class) UserPARM userPARM) {
        userService.updatePwd(userPARM.getPassword(), userPARM.getNewPassword());
        return success();
    }

    @PreAuth
    @ApiOperation("重置密码")
    @PostMapping("/resetPwd")
    public ApiResponses<Void> resetPwd(@RequestBody @Validated(value = UserPARM.ResetPwd.class) UserPARM userPARM) {
        userService.resetPwd(userPARM.getId(), userPARM.getPassword());
        return success();
    }

    @PreAuth
    @ApiOperation("导出")
    @PostMapping("/export")
    public ApiResponses<Void> export(HttpServletResponse response) throws IOException {
        List<User> userList = userService.list();
        ExcelUtil<User> util = new ExcelUtil<>(User.class);
        util.exportExcel(response, userList, "用户数据");
        return success();
    }
}

